#pragma once
/*--------------------------------------------------------------------------------
 * Adaptive Intelligence - Foundation Framework Class Library
 * Version 2.00
 * 
 * Domain End Point Class
 *      Represents a network endpoint using a domain name/ip address combination and
 * Internet port number.
 *------------------------------------------------------------------------------*/

/*--------------------------------------------------------------------------------
 * System Imports
 *------------------------------------------------------------------------------*/
#include "stdafx.h"

using namespace System;
using namespace System::Net::Sockets;

namespace Adaptive
{
	namespace Network
	{
		namespace Sockets
		{
			/// <summary>
			/// Represents a network endpoint using a domain name/ip address combination and
			/// Internet port number.
			/// </summary>
			public ref class DomainEndPoint : public IPEndPoint
			{
			public:
				/*--------------------------------------------------------------------------------
				 * Constructor / Dispose / Destructor Methods
				 *------------------------------------------------------------------------------*/
				#pragma region Constructor / Dispose / Destructor Methods
				/// <summary>
				/// Initializes a new instance of the class.
				/// </summary>
				/// <remarks>
				/// This is the default constructor.
				/// </remarks>
				DomainEndPoint();
				/// <summary>
				/// Initializes a new instance of the class.
				/// </summary>
				/// <param name="domainNameOrAddress">The domain name or IP address of the remote host.</param>
				/// <param name="internetPort">The Internet port number to connect to.</param>
				DomainEndPoint(String^ domainNameOrAddress, short internetPort);
				/// <summary>
				/// Initializes a new instance of the class.
				/// </summary>
				/// <param name="ipAddress">The <see cref="IPAddress"/> of the remote host.</param>
				/// <param name="internetPort">The Internet port number to connect to.</param>
				DomainEndPoint(IPAddress^ ipAddress, short internetPort);
				/// <summary>
				/// Initializes a new instance of the class.
				/// </summary>
				/// <param name="remoteEndPoint">
				/// The remote end point to connect to.
				/// </param>
				DomainEndPoint(IPEndPoint^ remoteEndPoint);
				#pragma endregion

				/*--------------------------------------------------------------------------------
				 * Public Properties
				 *------------------------------------------------------------------------------*/
				#pragma region Public Properties
				/// <summary>
				/// Gets or sets the domain/host name of the remote machine to connect to.
				/// </summary>
				/// <value>
				/// A string containing the IP or domain name of the remote machine.
				/// </value>
				/// <remarks>
				/// Setting this property will invoke a DNS query.
				/// </remarks>
				property String^ DomainName { String^ get(); void set (String^ value); } 
				/// <summary>
				/// Gets the list of domain names associated with the item.
				/// </summary>
				/// <value>
				/// A string array containing the various host names returned by the last DNS call.
				/// </value>
				property array<String^>^ DomainNameList { array<String^>^ get(); }
				/// <summary>
				/// Gets a value indicating whether the last DNS call was successful.
				/// </summary>
				/// <value>
				/// <b>true</b> if the DNS call succeeded; otherwise, <b>false</b>.
				/// </value>
				property bool DnsSuccessful { bool get(); }
				#pragma endregion
	 
			private:
				/*--------------------------------------------------------------------------------
				 * Private Member Declarations
				 *------------------------------------------------------------------------------*/
				#pragma region Private Member Declarations
				/// <summary>
				/// Remote host/domain name value.
				/// </summary>
				String^ _domainName;
				/// <summary>
				/// List of domain names.
				/// </summary>
				array<String^>^ _domainNameList;

				bool _dnsSuccess;
				#pragma endregion

				/*--------------------------------------------------------------------------------
				 * Public Methods / Functions
				 *------------------------------------------------------------------------------*/
				#pragma region Public Methods / Functions
				/// <summary>
				/// Removes the contents of the data from the object and resets the values to defaults.
				/// </summary>
				void Clear();
				/// <summary>
				/// Re-executes a DNS call to populate the internal fields.
				/// </summary>
				/// <summary>
				/// <b>true</b> if the DNS call succeeded; otherwise, <b>false</b>.
				/// </summary>
				bool TryDns();
				#pragma endregion

				/*--------------------------------------------------------------------------------
				 * Private Methods / Functions
				 *------------------------------------------------------------------------------*/
				#pragma region Private Methods / Functions
				/// <summary>
				/// Performs DNS resolution.
				/// </summary>
				void PerformDnsTask();
				#pragma endregion

			};
		}
	}
}